﻿#region Copyright (c) 2012-10, Olaf Kober <amarok.projects@gmail.com>
//================================================================================
//	Permission is hereby granted, free of charge, to any person obtaining a copy
//	of this software and associated documentation files (the "Software"), to deal
//	in the Software without restriction, including without limitation the rights
//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//	copies of the Software, and to permit persons to whom the Software is
//	furnished to do so, subject to the following conditions:
//
//	The above copyright notice and this permission notice shall be included in
//	all copies or substantial portions of the Software.
//
//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//	THE SOFTWARE.
//================================================================================
#endregion

#if TESTS

using System;
using NUnit.Framework;


namespace Amarok
{
	[TestFixture]
	public class Test_None
	{
		[Test]
		public void Test_Instance()
		{
			var instance1 = None.Instance;
			var instance2 = None.Instance;

			Assert.That(instance1, Is.Not.Null);
			Assert.That(instance2, Is.Not.Null);
			Assert.That(instance1, Is.SameAs(instance2));
		}

		[Test]
		public void Test_Clone_ICloneable()
		{
			var instance1 = None.Instance;
			var cloneableObject = (ICloneable)instance1;
			var instance2 = cloneableObject.Clone();

			Assert.That(instance1, Is.Not.Null);
			Assert.That(instance2, Is.Not.Null);
			Assert.That(instance1, Is.SameAs(instance2));
		}

		[Test]
		public void Test_Clone()
		{
			var instance1 = None.Instance;
			var instance2 = instance1.Clone();

			Assert.That(instance1, Is.Not.Null);
			Assert.That(instance2, Is.Not.Null);
			Assert.That(instance1, Is.SameAs(instance2));
		}

		[Test]
		public void Test_GetHashCode()
		{
			var instance = None.Instance;
			Assert.That(instance.GetHashCode(), Is.EqualTo(0));
		}

		[Test]
		public void Test_Equals_Object()
		{
			Object a = None.Instance;
			Object b = None.Instance;
			Object c = TestHelper.TestBinaryFormatterRoundtrip(None.Instance);
			Object d = TestHelper.TestDataContractRoundtrip(None.Instance);
			Object e = 123;

			// x.Equals(x) == true
			Assert.That(a.Equals(a), Is.True);
			Assert.That(b.Equals(b), Is.True);
			Assert.That(c.Equals(c), Is.True);
			Assert.That(d.Equals(d), Is.True);
			Assert.That(e.Equals(e), Is.True);

			// x.Equals(null) == false
			Assert.That(a.Equals(null), Is.False);
			Assert.That(b.Equals(null), Is.False);
			Assert.That(c.Equals(null), Is.False);
			Assert.That(d.Equals(null), Is.False);
			Assert.That(e.Equals(null), Is.False);

			// x.Equals(y)
			Assert.That(a.Equals(b), Is.True);
			Assert.That(a.Equals(c), Is.True);
			Assert.That(a.Equals(d), Is.True);
			Assert.That(a.Equals(e), Is.False);

			// y.Equals(x)
			Assert.That(b.Equals(a), Is.True);
			Assert.That(c.Equals(a), Is.True);
			Assert.That(d.Equals(a), Is.True);
			Assert.That(e.Equals(a), Is.False);
		}

		[Test]
		public void Test_Equals()
		{
			var a = None.Instance;
			var b = None.Instance;
			var c = TestHelper.TestBinaryFormatterRoundtrip(None.Instance);
			var d = TestHelper.TestDataContractRoundtrip(None.Instance);

			// x.Equals(x) == true
			Assert.That(a.Equals(a), Is.True);
			Assert.That(b.Equals(b), Is.True);
			Assert.That(c.Equals(c), Is.True);
			Assert.That(d.Equals(c), Is.True);

			// x.Equals(null) == false
			Assert.That(a.Equals(null), Is.False);
			Assert.That(b.Equals(null), Is.False);
			Assert.That(c.Equals(null), Is.False);
			Assert.That(d.Equals(null), Is.False);

			// x.Equals(y)
			Assert.That(a.Equals(b), Is.True);
			Assert.That(a.Equals(c), Is.True);
			Assert.That(a.Equals(d), Is.True);

			// y.Equals(x)
			Assert.That(b.Equals(a), Is.True);
			Assert.That(c.Equals(a), Is.True);
			Assert.That(d.Equals(a), Is.True);
		}

		[Test]
		public void Test_Operator_Equality()
		{
			var a = None.Instance;
			var b = None.Instance;
			var c = TestHelper.TestBinaryFormatterRoundtrip(None.Instance);
			var d = TestHelper.TestDataContractRoundtrip(None.Instance);

			// x == x -> true
#pragma warning disable 1718
			Assert.That(a == a, Is.True);
			Assert.That(b == b, Is.True);
			Assert.That(c == c, Is.True);
			Assert.That(d == d, Is.True);
#pragma warning restore 1718

			// x == null -> false
			Assert.That(a == null, Is.False);
			Assert.That(b == null, Is.False);
			Assert.That(c == null, Is.False);
			Assert.That(d == null, Is.False);

			// null == x -> false
			Assert.That(null == a, Is.False);
			Assert.That(null == b, Is.False);
			Assert.That(null == c, Is.False);
			Assert.That(null == d, Is.False);

			// x == y -> true/false
			Assert.That(a == b, Is.True);
			Assert.That(a == c, Is.True);
			Assert.That(a == d, Is.True);

			// y == x -> true/false
			Assert.That(b == a, Is.True);
			Assert.That(c == a, Is.True);
			Assert.That(d == a, Is.True);
		}

		[Test]
		public void Test_Operator_Unequality()
		{
			var a = None.Instance;
			var b = None.Instance;
			var c = TestHelper.TestBinaryFormatterRoundtrip(None.Instance);
			var d = TestHelper.TestBinaryFormatterRoundtrip(None.Instance);

			// x != x -> false
#pragma warning disable 1718
			Assert.That(a != a, Is.False);
			Assert.That(b != b, Is.False);
			Assert.That(c != c, Is.False);
			Assert.That(d != d, Is.False);
#pragma warning restore 1718

			// x != null -> true
			Assert.That(a != null, Is.True);
			Assert.That(b != null, Is.True);
			Assert.That(c != null, Is.True);
			Assert.That(d != null, Is.True);

			// null != x -> true
			Assert.That(null != a, Is.True);
			Assert.That(null != b, Is.True);
			Assert.That(null != c, Is.True);
			Assert.That(null != d, Is.True);

			// x != y -> true/false
			Assert.That(a != b, Is.False);
			Assert.That(a != c, Is.False);
			Assert.That(a != d, Is.False);

			// y != x -> true/false
			Assert.That(b != a, Is.False);
			Assert.That(c != a, Is.False);
			Assert.That(d != a, Is.False);
		}

		[Test]
		public void Test_ToString()
		{
			var instance = None.Instance;
			var text1 = instance.ToString();
			var text2 = instance.ToString();

			Assert.That(text1, Is.EqualTo("(None)"));
			Assert.That(text2, Is.EqualTo("(None)"));
			Assert.That(text1, Is.SameAs(text2));
		}

		[Test]
		public void Test_Serialization_BinaryFormatter()
		{
			var instance1 = None.Instance;
			var instance2 = TestHelper.TestBinaryFormatterRoundtrip(instance1);

			Assert.That(instance1, Is.Not.SameAs(instance2));
			Assert.That(instance1, Is.EqualTo(instance2));
		}

		[Test]
		public void Test_Serialization_DataContract()
		{
			var instance1 = None.Instance;
			var instance2 = TestHelper.TestDataContractRoundtrip(instance1);

			Assert.That(instance1, Is.Not.SameAs(instance2));
			Assert.That(instance1, Is.EqualTo(instance2));
		}

	}
}

#endif
